package hos.http;

import android.annotation.SuppressLint;
import android.os.Looper;
import android.util.Log;

import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * <p>Title: ThreadExecutor </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2023/8/9 20:54
 */
public class HttpThreadExecutor extends ThreadPoolExecutor {

    private static final AtomicInteger threadId = new AtomicInteger(0);

    private HttpThreadExecutor() {
        this(Runtime.getRuntime().availableProcessors());
    }

    private HttpThreadExecutor(int cpuCount) {
        super(0,
                Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadFactory() {
                    @SuppressLint("DefaultLocale")
                    @Override
                    public Thread newThread(Runnable r) {
                        Thread thread = new Thread(r, String.format("HttpThread_io_%d", threadId.getAndIncrement()));
                        thread.setDaemon(false);
                        return thread;
                    }
                });
    }

    public static HttpThreadExecutor get() {
        return new HttpThreadExecutor();
    }

    public static boolean isMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        //监控线程池耗时任务,线程创建数量,正在运行的数量
        Log.d("Thread: ", "activeCount:" + getActiveCount());
        Log.d("Thread: ", "ThreadName" + Thread.currentThread().getName());
    }

    public HttpThreadExecutor postIo(Runnable runnable) {
        execute(runnable);
        return this;
    }

    public HttpThreadExecutor postOnIo(Runnable runnable) {
        if (isMainThread()) {
            return postIo(runnable);
        } else {
            runnable.run();
        }
        return this;
    }

}
